/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ace.game.particle;

import ace.game.entity.Entity;
import ace.geometry.Vector2D;
import ace.geometry.Vertex2D;
import ace.system.GameRandom;
import java.util.Vector;
import javax.microedition.lcdui.Graphics;

/**
 *
 * @author Hallucinogen
 */
public class ParticleEmitter extends Entity {
	private ParticleEmitter() {
		position			= new Vertex2D();
		mParticles			= new Vector();
		mVectorRandomizer	= new Vector2D();
	}

	public ParticleEmitter(Vertex2D inPos, Vector2D initialDirection, Vector2D initialDirectionVariance,
			float initSpeed, float speedVariance, int maxParticle,
			long initLifeSpan, long lifeVariance,
			int initColor, int colorVariance, Vector2D initForce,
			Vector2D forceVariance, boolean deccelerating, boolean emitOnce) {
		this();
		position			= inPos;
		mInitialDirection	= initialDirection;
		mInitSpeed			= initSpeed;
		mSpeedVariance		= speedVariance;
		mMaxParticle		= maxParticle;
		mInitLifeSpan		= initLifeSpan;
		mLifeVariance		= lifeVariance;
		mInitColor			= initColor;
		mColorVariance		= colorVariance;
		mInitForce			= initForce;
		mForceVariance		= forceVariance;
        mDeccelerating      = deccelerating;
		mEmitOnce			= emitOnce;

		mAlive				= true;

		mInitialDirectionVariance = initialDirectionVariance;

		createParticle();
	}

	private void createParticle() {
		for (int i = 0; i < mMaxParticle; ++i) {
			Particle newParticle = new Particle(this);
			initializeParticle(newParticle);
			mParticles.addElement(newParticle);
		}
	}

	protected void initializeParticle(Particle particle) {
		final long lifeTime = mInitLifeSpan + (long)(mLifeVariance * GameRandom.floatRandom());

		Vector2D direction = new Vector2D(mInitialDirection);
		direction.x += mInitialDirectionVariance.x * GameRandom.floatRandom();
		direction.y += mInitialDirectionVariance.y * GameRandom.floatRandom();
		final float speed = getRandomizedSpeed();
		direction.x *= speed;
		direction.y *= speed;

		int newRed	= (mInitColor >> 16) % 256 + GameRandom.intRandom((mColorVariance >> 16) % 256);
		int newGreen	= (mInitColor >> 8) % 256 + GameRandom.intRandom((mColorVariance >> 8) % 256);
		int newBlue	= mInitColor % 256 + GameRandom.intRandom(mColorVariance % 256);

		if (newRed < 0)		newRed = 0;
		if (newRed > 255)	newRed = 255;
		if (newGreen < 0)	newGreen = 0;
		if (newGreen > 255)	newGreen = 255;
		if (newBlue < 0)	newBlue = 0;
		if (newBlue > 255)	newBlue = 255;

		final int newColor	= (newRed << 16) | (newGreen << 8) | newBlue;
		particle.initParticle(null, direction, lifeTime, newColor);
	}

	public float getRandomizedSpeed() {
		return mInitSpeed + mSpeedVariance * GameRandom.floatRandom();
	}

	public Vector2D getRandomizedForce() {
		mVectorRandomizer.randomizeVector(mForceVariance);

		final float speed = getRandomizedSpeed();
		mVectorRandomizer.x *= speed;
		mVectorRandomizer.y *= speed;

		mVectorRandomizer.add(mInitForce);
		return mVectorRandomizer;
	}

    boolean isDeccelerating() {
        return mDeccelerating;
    }

	public boolean isAlive() { return mAlive; }

	public void update(long time) {
		// update existing particle
		mAlive = false;
		for (int i = 0, n = mParticles.size(); i < n; ++i) {
			Particle particle = (Particle)mParticles.elementAt(i);
			particle.update(time);
			if (!particle.isAlive()) {
				if (!mEmitOnce) {
					initializeParticle(particle);
				}
			} else {
				mAlive = true;
			}
		}
	}

	public void draw(Graphics g, int startX, int startY, int endX, int endY) {
		for (int i = 0, n = mParticles.size(); i < n; ++i) {
			Particle particle = (Particle)mParticles.elementAt(i);
			particle.draw(g, startX, startY, endX, endY);
		}
	}

	protected Vector2D mInitialDirection;
	protected Vector2D mInitialDirectionVariance;
	protected float mInitSpeed;
	protected float mSpeedVariance;

	protected Vector mParticles;
	protected int mMaxParticle;
	protected long mInitLifeSpan;
	protected long mLifeVariance;
	protected boolean mAlive;

	protected Vector2D mInitForce;
	protected Vector2D mForceVariance;

	protected int mInitColor;
	protected int mColorVariance;
    protected boolean mDeccelerating;
	protected boolean mEmitOnce;

	protected Vector2D mVectorRandomizer;
}
